package org.dxy.middleware.dynamic.thread.pool.infrastructure.adapter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dxy.middleware.dynamic.thread.pool.domain.model.ThreadPoolAggregate;
import org.dxy.middleware.dynamic.thread.pool.domain.port.IThreadPoolRepository;
import org.dxy.middleware.dynamic.thread.pool.type.AdapterType;
import org.dxy.middleware.dynamic.thread.pool.type.AdapterTypeConstants;
import org.dxy.middleware.dynamic.thread.pool.type.Constants;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Repository;

/**
 * @ description:
 * @ author: dxy
 * @ createTime: 2025/10/1 15:21
 */
@Slf4j
@AdapterType(AdapterTypeConstants.REDIS)
@Repository
@RequiredArgsConstructor
public class RedisThreadPoolRepository implements IThreadPoolRepository {
    private final RedissonClient redissonClient;
    //格式说明： thread_pool:{appName}:{threadPoolName}
    ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void save(ThreadPoolAggregate threadPoolAggregate) {
        String key = Constants.configKey(threadPoolAggregate.getAppName(), threadPoolAggregate.getThreadPoolName());
        try {
            RBucket<String> bucket = redissonClient.getBucket(key);
            String json = objectMapper.writeValueAsString(threadPoolAggregate);
            bucket.set(json);
            log.info("已保存线程池聚合到 Redis -> key: {}", key);
        } catch (Exception e) {
            log.error("保存线程池聚合到 Redis 失败 -> key: {}, error: {}", key, e.getMessage(), e);
            throw new RuntimeException("Redis 保存失败", e);
        }
    }

    @Override
    public void refresh(ThreadPoolAggregate aggregate) {
        if (aggregate == null) {
            log.error("刷新线程池缓存失败，aggregate为空");
            return;
        }

        if (StringUtils.isBlank(aggregate.getAppName()) || StringUtils.isBlank(aggregate.getThreadPoolName())) {
            log.error("刷新线程池缓存失败，appName或threadPoolName为空，aggregate={}", aggregate);
            return;
        }

        String key = Constants.configKey(aggregate.getAppName(), aggregate.getThreadPoolName());

        try {
            String json = objectMapper.writeValueAsString(aggregate);
            redissonClient.getBucket(key).set(json);

            log.info("刷新线程池缓存成功，key={}, value={}", key, json);
        } catch (Exception e) {
            log.error("刷新线程池缓存失败，key={}, error={}", key, e.getMessage(), e);
        }
    }


    @Override
    public ThreadPoolAggregate findByAppNameAndThreadPoolName(String appName, String threadPoolName) {
        String key = Constants.configKey(appName, threadPoolName);
        RBucket<String> bucket = redissonClient.getBucket(key);
        String json = bucket.get();
        if (json == null) {
            return null;
        }
        try {
            return objectMapper.readValue(json, ThreadPoolAggregate.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("反序列化线程池配置失败，key=" + key, e);
        }
    }

}
